package x5.baas.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ws.rs.core.MediaType;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
@RequestMapping("/common")
public class CommonController {
	@Autowired
	private SessionFactory sessionFactory;
	
	@RequestMapping(value ="/query", method =RequestMethod.POST, consumes =MediaType.APPLICATION_JSON, produces =MediaType.APPLICATION_JSON)
	@ResponseBody
	public Map<String, List<Object>> query(@RequestBody Map<String, Map<String, Object>> querys) {
		Map<String, List<Object>> result = new HashMap<String, List<Object>>();
		Session session = sessionFactory.openSession();
		try {
			for (String queryName : querys.keySet()) {
				Query query = session.getNamedQuery(queryName);
				Map<String, Object> params = querys.get(queryName);
				query.setProperties(params);
				result.put(queryName, query.list());
			}
		} finally {
			session.close();
		}
		return result; 
	}
	
	
	@RequestMapping(value ="/save", method =RequestMethod.POST, consumes =MediaType.APPLICATION_JSON, produces =MediaType.APPLICATION_JSON)
	@ResponseBody
	public String save(@RequestBody Map<String, Map<String, List<Map<String, Object>>>> saves) {
		Session session = sessionFactory.openSession();
		try {
			Transaction tran = session.beginTransaction();
			try {
				for (String entityName : saves.keySet()) {
					Map<String, List<Map<String, Object>>> delta = saves.get(entityName);
					saveDelta(session, entityName, delta);
				}
				tran.commit();
			} catch (Exception e) {
				tran.rollback();
				throw new RuntimeException(e);
			}
		} finally {
			session.close();
		}
		return "";
	}
	
	private void saveMaps(Session session, String entityName, String recordState, List<Map<String, Object>> maps) {
		if ("new".equals(recordState)) {
			for (Map<String, Object> map : maps) {
				session.save(entityName, map);
			}
		} else if ("edit".equals(recordState)) {
			for (Map<String, Object> map : maps) {
				session.update(entityName, map);
			}
		} else if ("delete".equals(recordState)) {
			for (Map<String, Object> map : maps) {
				session.delete(entityName, map);
			}
		}
	}
	
	private void saveDelta(Session session, String entityName, Map<String, List<Map<String, Object>>> delta) {
		for (String recordState : delta.keySet()) {
			List<Map<String, Object>> maps = delta.get(recordState);
			saveMaps(session, entityName, recordState, maps);
		}
	}
	
}
